-- FormulaM
-- Create by weism
-- 公式管理

module("FormulaM", package.seeall);

-- 所有的公式信息
local formula = {};

-- 模块初始化
local _init = false;
function init()
    if _init then return end
    _init = true;
    formula = LOAD_PATH2("game/formula");
end

-- 调用公式
function invoke(name, ...)
    if formula[name] == "TBL" then
        formula[name] = LOAD_RUN("game/formula/" .. name);
    end

    return formula[name](...);
end

-- 获取公式
function getFormula(name)
    return formula[name];
end

-- 对目标所有附加属性为id的进行合并
function combineProp(fighters, id, key)
    local prop = { id, key, 0 };
    for _, fighter in pairs(fighters) do
        prop = PropM.combineMulti({prop, PropM.combine(fighter, id, key)});
    end
    return prop;
end

-- 对目标所有属性为attr的目标，根据ids列表的值（依次为火、水、雷、光、暗）取得对应attr的附加属性ID
-- 合并后返回
function combinePropByAttr(fighters, attr, ids, filterByAttr)
    filterByAttr = iif(filterByAttr == nil, true, filterByAttr);

    -- 依次为：火、水、雷、光、暗
    local id = ids[5];
    if (attr == FIRE)        then id = ids[1];
    elseif (attr == WATER)   then id = ids[2];
    elseif (attr == THUNDER) then id = ids[3];
    elseif (attr == LIGHTER) then id = ids[4];
    end

    local prop = { id, 0 };
    if (filterByAttr) then
        for _, fighter in pairs(CombatM.filterByAttr(fighters, attr)) do
            prop = PropM.combineMulti({prop, PropM.combine(fighter, id)});
        end
    else
        for _, fighter in pairs(fighters) do
            prop = PropM.combineMulti({prop, PropM.combine(fighter, id)});
        end
    end
    return prop;
end

-- 合并那种：XX系出战英雄攻击提升N%等类似的附加属性
-- ids: 依次为 精灵系、恶魔系、神祗系、亡灵系、人类系、巨龙系、魔兽系、机械系
function combinePropByStyle(fighters, style, ids, filterByStyle)
    filterByStyle = iif(filterByStyle == nil, true, filterByStyle);

    -- 依次为：精灵系、恶魔系、神祗系、亡灵系、人类系、巨龙系、魔兽系、机械系
    local id = ids[8];
    if (style == SPIRIT)     then id = ids[1];
    elseif (style == DEVIL)  then id = ids[2];
    elseif (style == GODS)   then id = ids[3];
    elseif (style == SOUL)   then id = ids[4];
    elseif (style == HUMAN)  then id = ids[5];
    elseif (style == DRAGON) then id = ids[6];
    elseif (style == WOW)    then id = ids[7];
    end

    local prop = { id, 0 };
    if (filterByStyle) then
        for _, fighter in pairs(CombatM.filterByStyle(fighters, style)) do
            prop = PropM.combineMulti({prop, PropM.combine(fighter, id)});
        end
    else
        for _, fighter in pairs(fighters) do
            prop = PropM.combineMulti({prop, PropM.combine(fighter, id)});
        end
    end
    return prop;
end


-- 取得需要抽取附加属性的攻击方/防守方集合
function FormulaM.getPropTargets(source)
    assert(false,"FormulaM.getPropTargets is invalid!");
    return { source };
    --[[
    local sources = {};
    if (source.type == OBJECT_TYPE_USER) then
        -- 玩家方，需要将出战宠物加进来
        table.insert(sources, source);
        table.insert(sources, source:getActivePet());

        -- 如果是在迷宫中，需要把召唤物加进来
        if DungeonM.isInDungeon() then
            local grids = DungeonM.getCurrentDungeon();
            if grids then
                for _, grid in pairs(grids) do
                    local summon = grid.summon;
                    if summon and not summon:isDead() and
                        (summon:query("enhance_user") == 1) then
                        table.insert(sources, summon);
                    end
                end
            end
        end
    else
        table.insert(sources, source);
    end

    return sources;    ]]
end

-- 筛选能升级的技能
function FormulaM.filterUpgradeSkills(skills)
    local ret = {};

    for _, skillId in pairs(skills) do
        local next = SkillM.query(skillId, "next");
        local level = SkillM.query(skillId, "level");
        -- 小于3级的才能升级
        if type(next) == "number" and next > 0 and level < 3 then
            table.insert(ret, skillId);
        end
    end

    -- 排序一遍
    table.sort(ret);

    return ret;
end

-- 地牢里还存活的怪物,flag=1表示是已经出现的怪物
function getAliveMonsters(flag)
    local grids = DungeonM.getCurrentDungeon();
    local ret = {};

    if not grids then
        return ret;
    end

    for _, grid in pairs(grids) do
        if (not flag or grid:isOpened()) and
            grid:isMonster() and
            not grid.monster:isDead() and
            not (grid.monster.isAudience and grid.monster:isAudience()) then
            table.insert(ret, grid.monster);
        end
    end

    return ret;
end

-- 获取召唤兽辅助者
function getSummonAids(who)
    local ret = {};

    -- 只有玩家/召唤兽才会有召唤兽辅助者
    if who.type ~= OBJECT_TYPE_USER and who.type ~= OBJECT_TYPE_SUMMON then
        return ret;
    end

    local grids = DungeonM.getCurrentDungeon();

    if not grids then
        return ret;
    end

    for _, grid in pairs(grids) do
        repeat
            -- 如果是召唤兽需要把自己剔除掉
            if who.type == OBJECT_TYPE_SUMMON then
                if grid:getPos() == who:getPos() then
                    break;
                end
            end

            local summon = grid.summon;

            -- 不是召唤兽
            if not summon or summon.type ~= OBJECT_TYPE_SUMMON then
                break;
            end

            -- 还未翻开
            if not grid:isOpened() then
                break;
            end

            -- 召唤兽死亡了
            if summon:isDead() then
                break;
            end

            table.insert(ret, summon);
        until true;
    end

    return ret;
end
